home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1990, 1991 Stanford University
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the name
- * Stanford may not be used in any advertising or publicity relating to
- * the software without the specific, prior written permission of
- * Stanford.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
- * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
- /* $Header: /Source/Media/collab/TimeLine/RCS/note.c,v 1.11 92/09/24 17:18:28 drapeau Exp $ */
- /* $Log: note.c,v $
- * Revision 1.11 92/09/24 17:18:28 drapeau
- * Added code to AddandDisplayNewNote(): when a new note is added, the
- * "setupTime" field is set to zero milliseconds, indicating that there is
- * no synchronization information for this note yet.
- * In addition to this, it might be prudent to set the current document's
- * syncHints flag to indicate that sync hints are no longer valid.
- *
- * Revision 1.1 91/10/03 17:38:27 chua
- * In DeleteNote, make adjustments to the XClearArea parameters so that
- * a deleted note is properly erased.
- *
- * Revision 1.0 91/09/30 16:59:15 chua
- * In ClearAllNotes, the parameter is now tlFrame, instead of an instrument head.
- *
- * Revision 0.81 91/09/26 18:02:51 chua
- * In CheckNoteSelected, do not deselect note if user has clicked on a previously
- * selected note.
- *
- * Revision 0.80 91/09/25 13:51:10 chua
- * Changed the instrument field, instInfo, to editInfo.
- * Changed InstrumentInfo to EditInfo.
- *
- * Revision 0.79 91/09/23 17:12:28 chua
- * Replaced the last parameter in calls to CheckNoteSelected by Error, which
- * indicates that there is no double click.
- * In line 585, change selectedInstrument to noteInstrument.
- *
- * Revision 0.78 91/09/20 11:40:42 chua
- *
- *
- * Revision 0.77 91/09/19 17:28:57 chua
- * Make sure that variables are initialized properly. Change formatting slightly,
- * so that (if, for, while) statements with only one statement in them will not have
- * braces.
- *
- * Revision 0.76 91/09/16 15:09:30 chua
- * In line 560, the CheckNoteSelected call was short of one parameter. This is now
- * remedied.
- *
- * Revision 0.75 91/09/04 15:10:34 chua
- * Deleted the OverlapErrorMessage function and replace the calls to it by
- * AlertMessage.
- *
- * Revision 0.74 91/08/26 14:21:52 chua
- * Removed the tlFrame->actualApps variable.
- *
- * Revision 0.73 91/08/21 16:57:22 chua
- * In CheckNoteSelected, do not deselect note if a double click event has occurred.
- *
- * Revision 0.72 91/08/19 19:19:08 chua
- * In the InsertNewNote routine, if notes are overlapping, try to move the new note to
- * be adjoining with the note being overlapped. If this is not possible, an error
- * message is displayed.
- *
- * In the AddandDisplayNewNote routine, if the document name returned is 'untitled' or
- * the duration field in the selection structure equals -1, do not add the new note,
- * since this means that the filename and/or selection is not specified in the media
- * application.
- *
- * Revision 0.71 91/08/16 17:01:41 chua
- * Removed some variables which are not used.
- *
- * Revision 0.70 91/08/08 14:26:51 chua
- * In AddandDisplayNewNote, check that the application is open before proceeding to insert.
- *
- * Revision 0.69 91/08/02 14:28:53 chua
- * Made changes to DrawMoveNote. Instead of using the absolute mouse position to draw
- * the new note, we use tlFrame->startX, which would have been set to the correct value
- * in the ScrollTimerNotify procedure.
- *
- * Revision 0.68 91/08/02 13:26:30 chua
- * Made changes to the moving note code so that it moves correctly under different zoom level
- * and across different canvas mappings.
- *
- * Revision 0.67 91/08/02 11:45:28 chua
- * Added new comments in the DrawMoveNote function.
- *
- * Revision 0.66 91/08/02 11:41:47 chua
- * In the AddandDisplayNewNote routine, take out the portion of code that checks if a note
- * previously existed and put the code in a new function, CheckNoteSelected.
- *
- * This new function will return 0 if the mouse click does not fall on any note, return 1 if
- * it falls on an unselected note, and 2 if it falls on a selected note.
- *
- * Another new function, DrawMoveNote is also added. This will draw a dragged note at its
- * new position, or back at its old position if there is an overlap error at the new position.
- *
- * Revision 0.65 91/07/22 15:19:54 chua
- * In the DeleteNote procedure, after clearing a note, redraw any pause markers that have been
- * partially erased.
- *
- * Revision 0.64 91/07/18 15:07:04 chua
- * In the DeleteNote procedure, after clearing a note, check to see if there are grid lines
- * that need to be redrawn over the cleared area.
- *
- * Revision 0.63 91/07/17 10:28:46 chua
- * In the DeleteNote procedure, there is no longer any need to check if we need to
- * redraw any anchors when deleting a note, since anchors are no longer drawn.
- *
- * Revision 0.62 91/07/09 17:00:35 chua
- * Removed a redundant variable, templastX.
- *
- * Revision 0.61 91/06/25 17:43:04 chua
- * Replaced all occurrences of the constant HalfSecondScale with the value 5 as the constant is not in
- * use anymore.
- * In the appropriate places, scale the positions of notes according to the zoom level, to cater for
- * zooming.
- *
- * Revision 0.60 91/06/05 16:18:40 chua
- * In the DeleteNote and AddandDisplayNewNote routines, delete the lines which hide the
- * info panel list and reshow it again after it is done updating. This is because the code
- * for doing this is now in the InitNotesInfo routine.
- *
- * In the CalculateNoteTime routine, use the duration found in the note structure instead
- * of subtracting the start time from the end time to get the duration.
- *
- * In the AddandDisplayNewNote routine, set the minimum duration of a new note to half a
- * second, if the value passed by the remote application is less than that.
- *
- *
- * Revision 0.59 91/06/04 17:55:06 chua
- * Correct an error in calls to OverlapErrorMessage, where previously there were no
- * parameters passed. There should be one parameter, tlFrame.
- *
- * Revision 0.58 91/06/04 17:37:21 chua
- * Added the copyright comments in the beginning of the file.
- *
- * Revision 0.57 91/06/04 17:28:08 chua
- * In the AddandDisplayNewNote routine, if the frame is the clipboard, only check if
- * an existing note has been clicked upon. Do not add a new note if the frame is the
- * clipboard (meaning, if the user tried clicking on the cable in the clipboard window to
- * insert a new note).
- *
- * Revision 0.56 91/06/04 10:43:20 chua
- * Added a call to UpdateHeader to update the header of the frame whenever
- * there is a change in the status of the change flag.
- *
- * Revision 0.55 91/06/03 11:11:58 chua
- * Make changes to accomodate multiple documents. This involves identifying
- * which is the current active window, that is, the one where the last mouse
- * click was done.
- *
- * Revision 0.54 91/05/30 12:07:52 chua
- * Added an extra parameter in the call to InitNotesInfo. The second parameter,
- * deselect, indicates if the currently selected note is to be deselected.
- *
- * Revision 0.53 91/05/29 18:30:59 chua
- *
- *
- * Revision 0.52 91/05/29 14:40:27 chua
- * Remove the ClearNoteInfoList function calls as the functionality of this procedure is replaced
- * by the new InitNotesInfo procedure.
- *
- * Revision 0.51 91/05/28 12:12:44 chua
- * *** empty log message ***
- *
- * Revision 0.50 91/05/24 16:37:13 chua
- * *** empty log message ***
- *
- * Revision 0.49 91/05/23 17:39:00 chua
- * *** empty log message ***
- *
- * Revision 0.48 91/05/22 16:40:22 chua
- *
- *
- * Revision 0.47 91/05/22 13:56:24 chua
- *
- *
- * Revision 0.46 91/05/22 11:41:03 chua
- * In the DeleteNote and AddandDisplayNewNote routines, include statements setting the XV_SHOW
- * attribute for the notes info panel list such that the panel list is not showing when update
- * is being done and only shown again when update is completed. New update routines are used,
- * instead of using avlist. Refer to notesInfo.c for more details.
- *
- * Revision 0.45 91/05/17 16:56:59 chua
- * *** empty log message ***
- *
- * Revision 0.44 91/05/15 14:53:42 chua
- * Replaced the part of code which deselects the previously selected note with the DeselectNote function
- * call.
- *
- *
- * Revision 0.43 91/05/15 14:11:15 chua
- * Changes in the function AddandDisplayNewNote. Since only one note is allowed to be selected for the
- * entire timeline instead of one note per instrument, code is added to check that the previously selected
- * instrument's note is deselected if the user has click on a note. The deselection is done both on the
- * canvas display as well as on the notes info panel list.
- *
- * The selectedInstrument pointer is set accordingly to the newly selected instrument (if appropriate, that iis,
- * if the user has clicked on a note and it is not the same previously selected note).
- *
- * Revision 0.42 1991/04/24 01:01:31 chua
- * The change here is that since the instInfo field (pointer to the instrument info pop-up window)
- * is never NULL now (as the pop-up window is created when the instrument is created), all the
- * statements which test for whether it is not NULL before executing some code is now irrelevant.
- * This means the code inside the if statements are now always executed.
- *
- * Revision 0.41 1991/04/08 21:12:43 chua
- * The new changes have to do with updating the instrument info pop-up windows.
- * DeleteNote function: If a note is to be deleted, the notes info panel list is first cleared by calling
- * the ClearNoteInfoList procedure. The numnotes counter in the instrument data structure
- * is then decremented, and the notes info panel list updated by calling the
- * InitNotesInfo procedure (notesInfo.c).
- * The above is done assuming the info pop-up window for the instrument has been created.
- * If not, the numnotes counter is decremented and none of the above updating of the
- * panel list takes place.
- *
- * CalculateNoteTime: This is a new function which will calculate the startMin, startSec, endMin, endSec,
- * durationMin, durationSec fields for a Note data structure.
- *
- * AddandDisplayNewNote: A check is first made to see if the info pop-up window for this instrument has
- * been created. If not, the function performs as before.
- * If yes, check if the user has click on a note. Depending on whether the note was
- * previously selected or not, it is highlighted or de-highlighted. The appropriate
- * entry in the info panel list is selected as well and the information about the
- * selected note loaded into the display fields in the pop-up window.
- * If a note has not been selected, proceed to insert the note as before. The only
- * difference is that at the end of this function, if the pop-up window has been created,
- * call this function again but with a xPos that is incremented by 1. The reason for
- * doing this is so that the newly inserted note will be detected as being clicked upon
- * in the second call and will be selected.
- *
- * Revision 0.40 1991/04/01 02:06:21 chua
- * This file contains the procedure for adding or delete a note from an instrument note list.
- * The functions are:
- * OverlapErrorMessage - prints an error message that indicates overlapping notes are not allowed.
- * ClearAllNotes - goes through all the instruments and delete all notes in the note list of each instrument.
- * InsertNewNote - insert a new note into the instrument's note list.
- * DeleteNote - delete a note from an instrument's note list and clear the note from the display.
- * AddandDisplayNewNote - Gets information on a note from the 'remote' application that the selected instrument
- * represents, calls InsertNewNote to add the new note in the note list and calls
- * DrawNote to display the new note on the canvas.
- * */
-
- static char notercsid[] = "$Header: /Source/Media/collab/TimeLine/RCS/note.c,v 1.11 92/09/24 17:18:28 drapeau Exp $";
-
- #include "main.h"
-
- /*
- * This function clears the note list in all the instruments. It frees the space allocated to all the notes and resets the notes count variable
- * for each instrument (numnotes) to zero.
- * Called by Load (file.c), UpdateAppsHandler (openApps.c)
- */
- void ClearAllNotes(tlFrame)
- TimeLineFramePtr tlFrame;
- {
- Instrument *instrument;
- Note *note, *freenote;
-
- instrument = tlFrame->instHead;
- while (instrument != NULL)
- {
- note = instrument->firstNote; /* Go through the whole note list and free each note */
- while (note != NULL)
- {
- freenote = note;
- note = note->next;
- free (freenote);
- }
- instrument->firstNote = NULL;
- instrument->infoNote = NULL;
- instrument->numnotes = 0;
- instrument = instrument->next;
- }
- }
-
- /*
- * This function will insert a new note into a given instrument's note list. Notes are stored in ascending order of their starting positions
- * on the timeline, meaning notes that are to be played first will be stored earlier in the list.
- * If a note overlaps with another, try to move it to be adjoining with the overlapping note. If this is not possible, print an error message.
- * Called by Load (file.c) and AddandDisplayNewNote (note.c)
- */
- int InsertNewNote (instrument, newNote, tlFrame)
- Instrument *instrument;
- Note *newNote;
- TimeLineFramePtr tlFrame;
- {
- Note *currentNote;
- Note *prevNote;
- int duration;
-
- duration = newNote->ms->duration * PixelsPerSecond / 2;
- if (instrument->firstNote == NULL) /* Note list is empty. Insert at the beginning. */
- instrument->firstNote = newNote;
- else /* Go down the note list to find the appropriate position to insert */
- {
- currentNote = instrument->firstNote;
- prevNote = instrument->firstNote;
- if (currentNote->start > newNote->start)
- {
- if (newNote->end <= currentNote->start) /* Insert at the beginning of the note list. */
- {
- newNote->next = currentNote;
- instrument->firstNote = newNote;
- return OK;
- }
- if (currentNote->start - duration >= 0) /* Move the new note so that it is before the current first note */
- { /* Make sure there is space to make the move */
- newNote->start = currentNote->start - duration;
- newNote->end = currentNote->start;
- CalculateNoteTime (newNote);
- newNote->next = currentNote;
- instrument->firstNote = newNote;
- return OK;
- }
- else /* Overlap note error */
- {
- AlertMessage(tlFrame, "There is not enough space to insert the new note.", NULL, NULL);
- return Error;
- }
- }
- else while (currentNote != NULL)
- {
- if (currentNote->start < newNote->start)
- {
- if (currentNote->end <= newNote->start)
- {
- if (currentNote->next == NULL) /* Insert at the end of list */
- {
- currentNote->next = newNote;
- return OK;
- }
- prevNote = currentNote;
- currentNote = currentNote->next;
- }
- else if (currentNote->next == NULL) /* Insert at the end of list, moving the new note to the end of the current note */
- {
- newNote->start = currentNote->end;
- newNote->end = currentNote->end + duration;
- CalculateNoteTime (newNote);
- InsertNewNote(instrument, newNote, tlFrame);
- return OK;
- }
- else if (currentNote->next->start >= currentNote->end + duration) /* Insert at the end of the current note, after making sure that there is */
- { /* enough space between the current note and the next note to make the insert */
- newNote->start = currentNote->end;
- newNote->end = currentNote->end + duration;
- CalculateNoteTime (newNote);
- InsertNewNote(instrument, newNote, tlFrame);
- return OK;
- }
- else /* No space to insert the new note */
- {
- AlertMessage(tlFrame, "There is not enough space to insert the new note.", NULL, NULL);
- return Error;
- }
- }
- else if (currentNote->start >= newNote->end) /* No overlapping problem. Just insert in the middle of a list */
- {
- prevNote->next = newNote;
- newNote->next = currentNote;
- return OK;
- }
- else if (currentNote->start - duration >= prevNote->end) /* Insert in the middle of the notes list, before the current note */
- {
- newNote->start = currentNote->start - duration;
- newNote->end = currentNote->start;
- CalculateNoteTime (newNote);
- InsertNewNote(instrument, newNote, tlFrame);
- return OK;
- }
- else /* No space to insert the new note */
- {
- AlertMessage(tlFrame, "There is not enough space to insert the new note.", NULL, NULL);
- return Error;
- }
- }
- }
- return OK;
- }
-
- /*
- * This function will delete a note from an instrument's note list. It takes as argument a pointer to the instrument node, and the X-coordinate
- * of the mouse click by the user on the canvas. This xPos is used to compare if the user has indeed click on a note.
- * The function will also update the info pop-up window if a note is to be deleted.
- * 1) Check if the instrument's note list is empty. If so, return, since this means there is no note to be deleted.
- * 2) Check if the first note is to be deleted. If so, after deletion, check if the note list is empty (there may be only one note in the note list
- * initially.
- * 3) Go through the note list to determine which note is to be deleted. This is done by comparing xPos to the start and end points of each note.
- * If xPos falls between this point, then that note is to be deleted, since no overlapping notes are allowed.
- * 4) If such a note (to be deleted) is found (indicated by the currentNote not being NULL), first we note the position of the playback head and
- * move it away. This is done just in case the playback head falls on the note. If it was not moved away, deleting the note will mess up the
- * drawing of the playback head later, since the color would be different and the XOR mode for the playback head would yield different colors.
- * 5) Now clear the area that the note occupied using XClearArea. Redraw the segment of the cable that has been erased, and redraw the grid lines
- * if necessary. Also redraw any pause markers that might have been partially erased.
- * 6) Clearing of the note is now done. The playback head is redrawn in its original position.
- * 7) The change flag is set to 1 and the deleted note is freed from memory.
- * Called by DrawCanvasEventHandler (canvas.c)
- */
- void DeleteNote(instrument, xPos, tlFrame)
- Instrument *instrument;
- int xPos;
- TimeLineFramePtr tlFrame;
- {
- Note *currentNote, *prevNote;
- Pause *pause;
- int found;
- int templastX;
- int i;
- int width;
- int gridStart;
-
- if (instrument->firstNote == NULL) /* Note list is empty, nothing to delete */
- return;
- currentNote = instrument->firstNote;
- if (xPos >= currentNote->start
- && xPos < currentNote->end) /* Check if the first note on the note list is to be deleted */
- instrument->firstNote = currentNote->next;
- else
- {
- prevNote = currentNote;
- currentNote = currentNote->next;
- found = 0;
- while (currentNote != NULL && !found)
- {
- if (xPos >= currentNote->start
- && xPos < currentNote->end) /* Found the note to be deleted */
- {
- prevNote->next = currentNote->next;
- found = 1;
- }
- prevNote = currentNote;
- if (!found) currentNote = currentNote->next;
- }
- }
- if (currentNote != NULL)
- {
- instrument->numnotes--; /* Decrement the number of notes counter */
- InitNotesInfo(instrument, 1, tlFrame);
- templastX = tlFrame->lastX; /* Remember the playback head position and move it away temporarily */
- DrawPlaybackHead(-1, tlFrame);
- width = (currentNote->end - currentNote->start) / tlFrame->zoomLevel;
- if (width < 2)
- width = 2;
- XClearArea(tlFrame->dpyDraw, tlFrame->xidDraw,
- (currentNote->start / tlFrame->zoomLevel) - tlFrame->canvasStart,
- instrument->cableStart - NoteHeight/2, width + 1,
- NoteHeight, FALSE);
- if (tlFrame->gridSpacing > 0) /* Check if the grid lines need to be redrawn */
- {
- gridStart = (currentNote->start / tlFrame->zoomLevel) - tlFrame->canvasStart;
- if (gridStart % tlFrame->gridSpacing != 0)
- gridStart = gridStart - gridStart % tlFrame->gridSpacing + tlFrame->gridSpacing;
- SetLineAttributes(tlFrame, 1);
- XSetForeground(tlFrame->dpyDraw, tlFrame->gc, (long)tlFrame->pixelTable[White]);
- for (i=gridStart; i < (currentNote->end / tlFrame->zoomLevel) - tlFrame->canvasStart;
- i += tlFrame->gridSpacing) /* Draw the grid lines */
- XDrawLine(tlFrame->dpyDraw, tlFrame->xidDraw, tlFrame->gc, i, instrument->cableStart - NoteHeight/2,
- i, instrument->cableStart + NoteHeight/2);
- SetLineAttributes(tlFrame, 2);
- }
- XSetForeground(tlFrame->dpyDraw, tlFrame->gc, (long)tlFrame->pixelTable[Black]); /* Redraw the segment of the cable that was erased */
- XFillRectangle(tlFrame->dpyDraw, tlFrame->xidDraw, tlFrame->gc,
- (currentNote->start / tlFrame->zoomLevel) - tlFrame->canvasStart,
- instrument->cableStart - CableHeight/2, width + 1,
- CableHeight);
- pause = tlFrame->pauseHead; /* Redraw any pause markers that have been partially erased */
- while (pause != NULL)
- {
- XSetForeground(tlFrame->dpyDraw, tlFrame->gc, (long)tlFrame->pixelTable[Red]);
- if (pause->position >= currentNote->start - 1 && pause->position <= currentNote->end)
- XDrawLine(tlFrame->dpyDraw, tlFrame->xidDraw, tlFrame->gc,
- (pause->position / tlFrame->zoomLevel) - tlFrame->canvasStart, instrument->cableStart - NoteHeight/2,
- (pause->position / tlFrame->zoomLevel) - tlFrame->canvasStart,
- instrument->cableStart + NoteHeight/2);
- pause = pause->next;
- }
- DrawPlaybackHead(templastX, tlFrame); /* Reposition the playback head to original position */
- tlFrame->change = 1; /* Set the change flag to 1 */
- UpdateHeader(tlFrame, 1);
- free (currentNote);
- }
- }
-
- /*
- * This function will calculate a note's start and end times as well as the duration fields in minutes and seconds.
- * It does this by converting the values in the start and end fields in the note data structure and calculating the appropriate minute and
- * second representations.
- * Called by Load (file.c), AddandDisplayNewNote (note.c)
- */
- void CalculateNoteTime (note)
- Note *note;
- {
- note->startSec = note->start / PixelsPerSecond; /* Compute the start and end times, and the duration for the note */
- note->startMin = note->startSec / 60;
- note->startSec = note->startSec - note->startMin * 60;
- note->endSec = note->end / PixelsPerSecond;
- note->endMin = note->endSec / 60;
- note->endSec = note->endSec - note->endMin * 60;
- note->durationSec = (note->ms->duration + 1) / 2;
- note->durationMin = note->durationSec / 60;
- note->durationSec = note->durationSec - note->durationMin * 60;
- }
-
- /*
- * This function will insert a new note into an instrument's note list. It takes as argument a pointer to the instrument node, and the X-coordinate
- * of the mouse click by the user on the canvas. The new note will be inserted at this new position.
- * The function will also update the info pop-up window if a note is to be deleted.
- * A check is made to see that the frame is not the clipboard and that the app is currently open before insertion is allowed to proceed.
- * 1) The function checks if the user has clicked on a note. If so, this note is highlighted (drawn Sunken) and the appropriate entry in the
- * Info Window Panel List is selected (if the Info Window has been created). Any previously selected note in the same or another instrument will be
- * deselected and its info window updated accordingly. If the user has clicked on a note that was previously selected, this note is deselected and
- * now no note is selected.
- * 2) A new media segment is created and its fields are filled by using the network protocol messages to talk to the application concerned.
- * Check that duration is not zero for the selection obtained from the remote application. Set the duration to a minimum of a half second if
- * it is less than that.
- * 3) If the duration field = -1 or the filename is 'untitled', do not add the new note, since this means there is no valid filename and/or
- * selection specified in the media application.
- * 4) A new note data structure is then created and initialized appropriately.
- * 5) The InsertNewnote procedure is now called to insert the new note in the instrument's note list. If there is an error in insertion,
- * for instance, the note overlaps with an existing one, both the note and media segment data structures are freed and the function returns.
- * 6) If insertion is successful, the number of notes counter is incremented.
- * 7) The function is then called again with the same arguments. Since the new note is now in the notelist, it will be detected and selected by
- * the first part of the function. xPos is incremented by 1 to make sure that it is within a note.
- * 8) If the Info Window has not been created, then the note is drawn in the Raised mode.
- * The DrawNote function is then called to draw the new note on the canvas display. The playback head is first moved away, the new note drawn,
- * and then the playback head moved back into position. This avoids drawing the note over the playback head, which will cause a 'dirty' line mark
- * when the playback head is drawn in a new position, due to the XOR drawing mode properties of the playback head.
- * Called by DrawCanvasEventHandler (canvas.c), and by itself.
- */
- void AddandDisplayNewNote (Instrument* instrument,
- int xPos,
- TimeLineFramePtr tlFrame)
- {
- MediaSegment* ms;
- Note* newNote;
- int result;
-
- if (xv_get(tlFrame->TimeLine_window->controls, PANEL_CLIENT_DATA) == 0) /* Clipboard document. No insertion allowed */
- return;
- if (CheckAppOpen(tlFrame, instrument, 1) == Error) /* Check if the application is alive */
- return;
- ms = (MediaSegment *) malloc (sizeof(MediaSegment)); /* Create a new media segment */
- result = SenderGetCurrentDocName(instrument->sender, &(ms->documentName)); /* Get the document name from the remote application */
- if (result == -1)
- return;
- result = SenderGetSelection(instrument->sender,&ms->selection); /* Get the selection data structure from the remote application */
- if (result == -1)
- return;
- if (ms->selection->duration != -1 && /* Insert only if there is a valid filename and selection */
- strcmp(ms->documentName, "untitled") != 0)
- {
- ms->setupTime = 0; /* This new note has no synchronization hints yet */
- ms->duration = ms->selection->duration / 500;
- if (ms->duration == 0 && ms->selection->duration >= 0) /* Set the minimum duration to half a second even if the selection */
- ms->duration = 1;
- newNote = (Note *) malloc (sizeof(Note)); /* Create a new Note data structure and initialize it */
- newNote->start = xPos;
- newNote->end = xPos + ms->duration * PixelsPerSecond / 2;
- newNote->ms = ms;
- CalculateNoteTime (newNote);
- newNote->next = NULL;
- if (InsertNewNote (instrument, newNote, tlFrame) == Error) /* Check if inserting the new note into the instrument's note list is */
- { /* successful. */
- free (ms); /* If not, free the ms and newNote data structures and return */
- free (newNote);
- return;
- }
- instrument->numnotes++; /* Increment the count of notes for this instrument */
- InitNotesInfo(instrument, 1, tlFrame);
- tlFrame->change = 1; /* Set the change flag to 1 (since there is a change) */
- UpdateHeader(tlFrame, 1);
- CheckNoteSelected(instrument, xPos + 1, tlFrame, Error);
- }
- }
-
- /*
- * This function checks if xPos falls on a note currently on the TimeLine. If so, it returns a value of 1 if the note was previously unselected,
- * a value of 2 if the note is already selected. A value of 0 is returned if xPos does not fall on any note.
- * The parameter doubleClick is used to check if this function is called when a double click has been detected. If so, do not deselect any previously
- * selected note.
- */
- int CheckNoteSelected (instrument, xPos, tlFrame, doubleClick)
- Instrument *instrument;
- int xPos;
- TimeLineFramePtr tlFrame;
- int doubleClick;
- {
- Note *currentNote;
- int noteCount = 0;
- int sameNote = 0;
- int found = 0;
-
- currentNote = instrument->firstNote;
- while (currentNote != NULL && !found)
- {
- if (xPos >= currentNote->start
- && xPos < currentNote->end) /* Check if the user has clicked on a note */
- { /* If so, highlight the note and select this note entry on the info window panel list */
- if (instrument->infoNote == currentNote && /* Check if the user has clicked on a previously selected< note */
- tlFrame->noteInstrument == instrument)
- {
- sameNote = 1;
- found = 2;
- if (doubleClick == OK)
- found = 1;
- }
- if (doubleClick != OK && found != 2) /* Deselect note only if not a double click */
- DeselectNote(tlFrame); /* Deselect a previously selected note, if any */
- if (sameNote == 0) /* Perform the following only if we are selecting a new note, and not deselecting */
- { /* a previously selected one. */
- found = 1;
- instrument->selectedInfoNote = noteCount; /* Set the selected note variables to this note */
- instrument->infoNote = currentNote;
- SelectNoteInfo (instrument, tlFrame); /* Select the note */
- xv_set(instrument->editInfo->NoteInfoList,
- PANEL_LIST_SELECT, instrument->selectedInfoNote, TRUE,
- NULL);
- }
- }
- currentNote = currentNote->next;
- noteCount++;
- }
- return found;
- }
-
- /*
- * This function will draw a note at its new position after it has been dragged. If this new position will cause a note overlap, an error message
- * is printed, and the note will be redrawn at its original position.
- * The note is deleted at its old position, and a copy of it is created. This copy is then inserted at the new position, or back at the old position if
- * an error occurs while inserting at the new position.
- */
- void DrawMoveNote (instrument, tlFrame, offset)
- Instrument *instrument;
- TimeLineFramePtr tlFrame;
- int offset;
- {
- Note *newNote;
- int noteX;
- int start;
- int end;
- int change;
-
- XDrawRectangle(tlFrame->dpyDraw, tlFrame->xidDraw, tlFrame->gcLine, /* Clear the drag note outline */
- (tlFrame->startX / tlFrame->zoomLevel) - tlFrame->canvasStart - offset,
- instrument->cableStart - NoteHeight/2,
- (instrument->infoNote->ms->duration * PixelsPerSecond) / (2 * tlFrame->zoomLevel),
- NoteHeight);
-
- newNote = (Note *) malloc (sizeof(Note)); /* Create a new Note data structure and initialize it */
- newNote->ms = instrument->infoNote->ms;
- start = instrument->infoNote->start;
- end = instrument->infoNote->start + instrument->infoNote->ms->duration * 5;
- newNote->next = NULL;
- change = tlFrame->change;
- DeleteNote(instrument, instrument->infoNote->start, tlFrame); /* Delete the note at its old position */
- noteX = (tlFrame->startX / tlFrame->zoomLevel) - tlFrame->canvasStart - offset;
- if (tlFrame->gridSpacing > 0) /* Snap to grid line if necessary */
- noteX = noteX - noteX % tlFrame->gridSpacing;
- noteX = (noteX + tlFrame->canvasStart) * tlFrame->zoomLevel;
- if (noteX < 0)
- noteX = 0;
- newNote->start = noteX;
- newNote->end = noteX + newNote->ms->duration * 5;
- CalculateNoteTime (newNote);
- tlFrame->change = 1; /* Set the change flag to 1 (since there is a change) */
- if (InsertNewNote (instrument, newNote, tlFrame) == Error) /* Check if insert of the note at the new position is successful */
- {
- newNote->start = start;
- newNote->end = end;
- CalculateNoteTime (newNote);
- InsertNewNote (instrument, newNote, tlFrame); /* Insert the note back at the old position */
- tlFrame->change = change; /* Set the change flag to whatever its value was before the attempted note move */
- }
- instrument->numnotes++; /* Increment the count of notes for this instrument */
- InitNotesInfo(instrument, 1, tlFrame);
- UpdateHeader(tlFrame, tlFrame->change);
- CheckNoteSelected(instrument, newNote->start, tlFrame, Error); /* The note at its new position will be drawn in this routine */
- }
-
-